home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 11 / FM Towns Free Software Collection 11.iso / t_os / tool / artemis1 / src / smooth.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-10-11  |  13.0 KB  |  516 lines

  1. /*
  2.     smooth.c
  3.  
  4.     戸田浩氏のスムース処理を解析するための一時ソース
  5. */
  6.  
  7. #include <stdlib.h>
  8. #include <stdlib.h>
  9.  
  10. #include "ge.h"
  11. #include "imageman.h"
  12. #include "dispman.h"
  13.  
  14.  
  15. #define    MYSpoint    EIMpoint
  16.  
  17.  
  18. void commandSmooth()
  19. {
  20.     for (;;)
  21.     {
  22.         if (area_input(AREA_POLYGON) != 0)
  23.             break;
  24.         EIMbackup();
  25.         smooth(28,0);
  26.     }
  27. }
  28.  
  29. #if 1
  30. // 1993.6.12
  31.  
  32. smooth( rate, rnd )
  33. int rate, rnd;
  34. {
  35.     int ax1, ay1, ax2, ay2, a, b, c, d, cmp;
  36.     int start, mid, fine, mode, r, s, x, y;
  37.     int k0, k1, k2;
  38.     int mp[4];
  39.  
  40.     area_getboundxy(&ax1,&ay1,&ax2,&ay2);
  41.     s = 32 - rate;            /* sharp rate */
  42.     r = rnd;
  43.  
  44.     for( y=ay1+1 ; y<=ay2-1 ; y++ ){
  45.         mode = 0;
  46.         for( x=ax1+1 ; x<=ax2-1 ; x++ ){
  47.             a = EIMpoint_back(x,y);        // a=WORD(bbuf+vadd+x*2);
  48.             b = EIMpoint_back(x,y+1);    // b=WORD(bbuf+vadd+x*2+1024);
  49.             c = EIMpoint_back(x+1,y);    // c=WORD(bbuf+vadd+x*2+2);
  50.             d = EIMpoint_back(x+1,y-1);    // d=WORD(bbuf+vadd+x*2-1022);
  51.             cmp = cmpdata( a, b, s );
  52.             if( (mode == 0) && cmp ){
  53.                 mode = 1;
  54.                 start = x;
  55.                 k0 = 0;
  56.             }
  57.             if( (mode == 1) && (cmp == 0) )mode = 0;
  58.             if( (mode == 2) && (cmpdata( a, d, s ) == 0) ){
  59.                 mode = 0;
  60.                 fine = x;
  61.                 smooth1( start, mid, fine, y, r );
  62.                 x = mid;
  63.             }
  64.             if( mode == 1 ){
  65.               k1 = katamuki( x, y );
  66.               if( cmpdata(a,c,s) ){
  67.                 if( (k1 <= k0) && (k1 < 0) ){
  68.                   k2 = katamuki( x+1, y );
  69.                   if( (k1 <= k2) || (cmpdata(b,c,12) == 0) ){
  70.                     mode = 2;
  71.                     mid = x;
  72.                   }
  73.                 }
  74.               }
  75.               k0 = k1;
  76.             }
  77.             if( (mode == 2) && (cmpdata( c, d, s ) == 0) ){
  78.                 mode = 0;
  79.                 fine = x;
  80.                 smooth1( start, mid, fine, y, r );
  81.                 x = mid;
  82.             }
  83.         }
  84.     }
  85.     for( y=ay1+1 ; y<=ay2-1 ; y++ ){
  86.         mode = 0;
  87.         for( x=ax2-1 ; x>=ax1+1 ; x-- ){
  88.             a = EIMpoint_back(x,y);        // a=WORD(bbuf+vadd+x*2);
  89.             b = EIMpoint_back(x,y+1);    // b=WORD(bbuf+vadd+x*2+1024);
  90.             c = EIMpoint_back(x-1,y);    // c=WORD(bbuf+vadd+x*2-2);
  91.             d = EIMpoint_back(x-1,y-1);    // d=WORD(bbuf+vadd+x*2-1026);
  92.             cmp = cmpdata( a, b, s );
  93.             if( (mode == 0) && cmp ){
  94.                 mode = 1;
  95.                 start = x;
  96.                 k0 = 0;
  97.             }
  98.             if( (mode == 1) && (cmp == 0) )mode = 0;
  99.             if( (mode == 2) && (cmpdata( a, d, s ) == 0) ){
  100.                 mode = 0;
  101.                 fine = x;
  102.                 smooth2( start, mid, fine, y, r );
  103.                 x = mid;
  104.             }
  105.             if( mode == 1 ){
  106.               k1 = katamuki( x, y );
  107.               if( cmpdata(a,c,s) ){
  108.                 if( (k1 >= k0) && (k1 > 0) ){
  109.                   k2 = katamuki( x-1, y );
  110.                   if( (k1 >= k2) || (cmpdata(b,c,12) == 0) ){
  111.                 mode = 2;
  112.                 mid = x;
  113.                   }
  114.                 }
  115.               }
  116.               k0 = k1;
  117.             }
  118.             if( (mode == 2) && (cmpdata( c, d, s ) == 0) ){
  119.                 mode = 0;
  120.                 fine = x;
  121.                 smooth2( start, mid, fine, y, r );
  122.                 x = mid;
  123.             }
  124.         }
  125.     }
  126.  
  127.     for( x=ax1+1 ; x<=ax2-1 ; x++ ){
  128.         // vadd = x*2; mode = 0;
  129.         mode = 0;
  130.         for( y=ay1+1 ; y<=ay2-1 ; y++ ){
  131.             a = EIMpoint_back(x,y);        // a=WORD(bbuf+vadd+y*1024);
  132.             b = EIMpoint_back(x+1,y);    // b=WORD(bbuf+vadd+y*1024+2);
  133.             c = EIMpoint_back(x,y+1);    // c=WORD(bbuf+vadd+y*1024+1024);
  134.             d = EIMpoint_back(x-1,y+1);    // d=WORD(bbuf+vadd+y*1024+1022);
  135.             cmp = cmpdata( a, b, s );
  136.             if( (mode == 0) && cmp ){
  137.                 mode = 1;
  138.                 start = y;
  139.                 k0 = 0;
  140.             }
  141.             if( (mode == 1) && (cmp == 0) )mode = 0;
  142.             if( (mode == 2) && (cmpdata( a, d, s ) == 0) ){
  143.                 mode = 0;
  144.                 fine = y;
  145.                 smooth3( start, mid, fine, x, r );
  146.                 y = mid;
  147.             }
  148.             if( mode == 1 ){
  149.               k1 = katamuki( x, y );
  150.               if( cmpdata(a,c,s) ){
  151.                 if( (k1 <= k0) && (k1 < 0) ){
  152.                   k2 = katamuki( x, y+1 );
  153.                   if( (k1 <= k2) || (cmpdata(b,c,12) == 0) ){
  154.                 mode = 2;
  155.                 mid = y;
  156.                   }
  157.                 }
  158.               }
  159.               k0 = k1;
  160.             }
  161.             if( (mode == 2) && (cmpdata( c, d, s ) == 0) ){
  162.                 mode = 0;
  163.                 fine = y;
  164.                 smooth3( start, mid, fine, x, r );
  165.                 y = mid;
  166.             }
  167.         }
  168.     }
  169.  
  170.     for( x=ax2-1 ; x>=ax1+1 ; x-- ){
  171.         // vadd = x*2; mode = 0;
  172.         mode = 0;
  173.         for( y=ay1+1 ; y<=ay2-1 ; y++ ){
  174.             a = EIMpoint_back(x,y);        // a=WORD(bbuf+vadd+y*1024);
  175.             b = EIMpoint_back(x-1,y);    // b=WORD(bbuf+vadd+y*1024-2);
  176.             c = EIMpoint_back(x,y+1);    // c=WORD(bbuf+vadd+y*1024+1024);
  177.             d = EIMpoint_back(x+1,y+1);    // d=WORD(bbuf+vadd+y*1024+1026);
  178.             cmp = cmpdata( a, b, s );
  179.             if( (mode == 0) && cmp ){
  180.                 mode = 1;
  181.                 start = y;
  182.                 k0 = 0;
  183.             }
  184.             if( (mode == 1) && (cmp == 0) )mode = 0;
  185.             if( (mode == 2) && (cmpdata( a, d, s ) == 0) ){
  186.                 mode = 0;
  187.                 fine = y;
  188.                 smooth4( start, mid, fine, x, r );
  189.                 y = mid;
  190.             }
  191.             if( mode == 1 ){
  192.               k1 = katamuki( x, y );
  193.               if( cmpdata(a,c,s) ){
  194.                 if( (k1 >= k0) && (k1 > 0) ){
  195.                   k2 = katamuki( x, y+1 );
  196.                   if( (k1 >= k2) || (cmpdata(b,c,12) == 0) ){
  197.                 mode = 2;
  198.                 mid = y;
  199.                   }
  200.                 }
  201.               }
  202.               k0 = k1;
  203.             }
  204.             if( (mode == 2) && (cmpdata( c, d, s ) == 0) ){
  205.                 mode = 0;
  206.                 fine = y;
  207.                 smooth4( start, mid, fine, x, r );
  208.                 y = mid;
  209.             }
  210.         }
  211.     }
  212. }
  213.  
  214. katamuki( x, y )        /* return=(karamuki + or 0 or -) s=rate */
  215. int x, y;
  216. {
  217.     int p[3][3];
  218.     int ck;
  219.  
  220.     // vadd = y*1024;
  221.     ck = 0;
  222.     if (x-1<0 || y-1<0 || EIMgetxsize()<=x+1 || EIMgetysize()<=y+1)
  223.         return 0;
  224.     // if( (vadd+x*2-1026 < 0) || (vadd+x*2+1026 > 524286) )return 0;
  225.     // 座標チェック!
  226.     p[0][0] = EIMpoint_back(x-1,y-1);    // p[0][0]=WORD(bbuf+vadd+x*2-1026);
  227.     p[0][1] = EIMpoint_back(x  ,y-1);    // p[0][1]=WORD(bbuf+vadd+x*2-1024);
  228.     p[0][2] = EIMpoint_back(x+1,y-1);    // p[0][2]=WORD(bbuf+vadd+x*2-1022);
  229.     p[1][0] = EIMpoint_back(x-1,y  );    // p[1][0]=WORD(bbuf+vadd+x*2-2);
  230.     p[1][1] = EIMpoint_back(x  ,y  );    // p[1][1]=WORD(bbuf+vadd+x*2);
  231.     p[1][2] = EIMpoint_back(x+1,y  );    // p[1][2]=WORD(bbuf+vadd+x*2+2);
  232.     p[2][0] = EIMpoint_back(x-1,y+1);    // p[2][0]=WORD(bbuf+vadd+x*2+1022);
  233.     p[2][1] = EIMpoint_back(x  ,y+1);    // p[2][1]=WORD(bbuf+vadd+x*2+1024);
  234.     p[2][2] = EIMpoint_back(x+1,y+1);    // p[2][2]=WORD(bbuf+vadd+x*2+1026);
  235.  
  236.     ck = ck - kata_s( p[0][0], p[1][1] );
  237.     ck = ck - kata_s( p[0][1], p[1][2] );
  238.     ck = ck - kata_s( p[1][0], p[2][1] );
  239.     ck = ck - kata_s( p[1][1], p[2][2] );
  240.  
  241.     ck = ck + kata_s( p[0][1], p[1][0] );
  242.     ck = ck + kata_s( p[0][2], p[1][1] );
  243.     ck = ck + kata_s( p[1][1], p[2][0] );
  244.     ck = ck + kata_s( p[1][2], p[2][1] );
  245.  
  246.     return ck;
  247. }
  248.  
  249. kata_s( a, b )        /* total abs(sub) */
  250. int a, b;
  251. {
  252.     int data1, data2, subd, add;
  253.  
  254.     data1 = a & 0x1f; data2 = b & 0x1f;
  255.     subd = data2 - data1; if( subd < 0 )subd = -subd;
  256.     add = subd;
  257.     data1 = (a >> 5) & 0x1f; data2 = (b >> 5) & 0x1f;
  258.     subd = data2 - data1; if( subd < 0 )subd = -subd;
  259.     add = add + subd;
  260.     data1 = (a >> 10) & 0x1f; data2 = (b >> 10) & 0x1f;
  261.     subd = data2 - data1; if( subd < 0 )subd = -subd;
  262.     add = add + subd;
  263.     return add;
  264. }
  265.  
  266. cmpdata( a, b, rate )
  267. int a, b, rate;
  268. {
  269.     int data1, data2, subd;
  270.  
  271.     data1 = a & 0x1f; data2 = b & 0x1f;
  272.     subd = data2 - data1; if( subd < 0 )subd = -subd;
  273.     if( subd > rate )return 1;
  274.     data1 = (a >> 5) & 0x1f; data2 = (b >> 5) & 0x1f;
  275.     subd = data2 - data1; if( subd < 0 )subd = -subd;
  276.     if( subd > rate )return 1;
  277.     data1 = (a >> 10) & 0x1f; data2 = (b >> 10) & 0x1f;
  278.     subd = data2 - data1; if( subd < 0 )subd = -subd;
  279.     if( subd > rate )return 1;
  280.     return 0;
  281. }
  282.  
  283. smooth1( st, md, fn, y, r )        /* r=random( 0-256 ) */
  284. int st, md, fn, y, r;
  285. {
  286.     int x1, x2, x3;
  287.     int i, n, top, rate, a, b, c;
  288.  
  289.     x1 = ( st + md ) >> 1;
  290.     x2 = md;
  291.     x3 = ( md + fn + 1 ) >> 1;
  292.     top = y*1024;
  293.     if( x1 == x2 )goto smoo1;
  294.     rate = 128/(x2-x1+1);
  295.     n = 1;
  296.     for( i=x1 ; i<=x2-1 ; i++ ){
  297.         a = EIMpoint_back(i,y+1); // a = WORD( bbuf+top+i*2+1024 );
  298.         b = MYSpoint(i,y); // b = peekw( top+i*2, 0x10c );
  299.         if( area_chkxy(i,y) /* && (b < 0x8000) マスク */ ){
  300.             c = mix( a, b, n*rate, r );
  301.             EIMpset( i,y, c, DrawNORMAL );
  302.         }
  303.         n++;
  304.     }
  305.     if( x2 == x3 )goto smoo2;
  306. smoo1:    if( x2 == x3 )return 0;
  307.     rate = 128/(x3-x2+1);
  308.     n = 1;
  309.     for( i=x2+1 ; i<=x3 ; i++ ){
  310.         a = EIMpoint_back(i,y-1); // a = WORD( bbuf+top+i*2-1024 );
  311.         b = MYSpoint(i,y); //  b = peekw( top+i*2, 0x10c );
  312.         if( area_chkxy(i,y) /* && (b < 0x8000) */){
  313.             c = mix( a, b, (128 - n*rate), r );
  314.             EIMpset(i,y,c,DrawNORMAL);
  315.         }
  316.         n++;
  317.     }
  318. smoo2:
  319.     a = MYSpoint(x2-1,y);    // a = peekw( top+x2*2-2, 0x10c );
  320.     b = MYSpoint(x2+1,y);    // b = peekw( top+x2*2+2, 0x10c );
  321.     if( area_chkxy(x2,y) /* && (b < 0x8000) */){
  322.         c = mix( a, b, 128, r );
  323.         EIMpset(x2,y,c,DrawNORMAL);  // pokew( top+x2*2, 0x10c, c );
  324.     }
  325.     return 0;
  326. }
  327.  
  328. smooth2( st, md, fn, y, r )        /* r=random( 0-256 ) */
  329. int st, md, fn, y, r;
  330. {
  331.     int x1, x2, x3;
  332.     int i, n, top, rate, a, b, c;
  333.  
  334.     x1 = ( st + md + 1 ) >> 1;
  335.     x2 = md;
  336.     x3 = ( md + fn ) >> 1;
  337.     top = y*1024;
  338.     if( x1 == x2 )goto smoo1;
  339.     rate = 128/(x1-x2+1);
  340.     n = 1;
  341.     for( i=x1 ; i>=x2+1 ; i-- ){
  342.         a = EIMpoint_back(i,y+1);    // a = WORD( bbuf+top+i*2+1024 );
  343.         b = MYSpoint(i,y);            // b = peekw( top+i*2, 0x10c );
  344.         if( area_chkxy(i,y) /* && (b < 0x8000) */ ){
  345.             c = mix( a, b, n*rate, r );
  346.             EIMpset(i,y,c,DrawNORMAL);    // pokew( top+i*2, 0x10c, c );
  347.         }
  348.         n++;
  349.     }
  350.     if( x2 == x3 )goto smoo2;
  351. smoo1:
  352.     if( x2 == x3 )return 0;
  353.     rate = 128/(x2-x3+1);
  354.     n = 1;
  355.     for( i=x2-1 ; i>=x3 ; i-- ){
  356.         a = EIMpoint_back(i,y-1);    // a = WORD( bbuf+top+i*2-1024 );
  357.         b = MYSpoint(i,y);    // b = peekw( top+i*2, 0x10c );
  358.         if( area_chkxy(i,y) /* && (b < 0x8000) */){
  359.             c = mix( a, b, (128 - n*rate), r );
  360.             EIMpset(i,y,c,DrawNORMAL); // pokew( top+i*2, 0x10c, c );
  361.         }
  362.         n++;
  363.     }
  364. smoo2:
  365.     a = MYSpoint(x2+1,y); // a = peekw( top+x2*2+2, 0x10c );
  366.     b = MYSpoint(x2-1,y); // b = peekw( top+x2*2-2, 0x10c );
  367.     if( area_chkxy(x2,y) /* && (b < 0x8000) */){
  368.         c = mix( a, b, 128, r );
  369.         EIMpset(x2,y,c,DrawNORMAL); // pokew( top+x2*2, 0x10c, c );
  370.     }
  371.     return 0;
  372. }
  373.  
  374. smooth3( st, md, fn, x, r )
  375. int st, md, fn, x, r;
  376. {
  377.     int y1, y2, y3;
  378.     int i, n, top, rate, a, b, c;
  379.  
  380.     y1 = ( st + md ) >> 1;
  381.     y2 = md;
  382.     y3 = ( md + fn ) >> 1;
  383.     top = x*2;
  384.     if( y1 == y2 )goto smoo1;
  385.     rate = 128/(y2-y1+1);
  386.     n = 1;
  387.     for( i=y1 ; i<=y2-1 ; i++ ){
  388.         a = EIMpoint_back(x+1,i); // a = WORD( bbuf+top+i*1024+2 );
  389.         b = MYSpoint(x,i); // b = peekw( top+i*1024, 0x10c );
  390.         if( area_chkxy(x,i) /*  && (b < 0x8000) */ ){
  391.             c = mix( a, b, n*rate, r );
  392.             EIMpset(x,i,c,DrawNORMAL); // pokew( top+i*1024, 0x10c, c );
  393.         }
  394.         n++;
  395.     }
  396.     if( y2 == y3 )goto smoo2;
  397. smoo1:
  398.     if( y2 == y3 )return 0;
  399.     rate = 128/(y3-y2+1);
  400.     n = 1;
  401.     for( i=y2+1 ; i<=y3 ; i++ ){
  402.         a = EIMpoint_back(x-1,i); // a = WORD( bbuf+top+i*1024-2 );
  403.         b = MYSpoint(x,i); // b = peekw( top+i*1024, 0x10c );
  404.         if( area_chkxy(x,i) /* && (b < 0x8000) */ ){
  405.             c = mix( a, b, (128 - n*rate), r );
  406.             EIMpset(x,i,c,DrawNORMAL); // pokew( top+i*1024, 0x10c, c );
  407.         }
  408.         n++;
  409.     }
  410. smoo2:
  411.     a = MYSpoint(x,y2+1); // a = peekw( top+y2*1024+1024, 0x10c );
  412.     b = MYSpoint(x,y2-1); // b = peekw( top+y2*1024-1024, 0x10c );
  413.     if( area_chkxy(x,y2) /*  && (b < 0x8000) */ ){
  414.         c = mix( a, b, 128, r );
  415.         EIMpset(x,y2,c,DrawNORMAL); // pokew( top+y2*1024, 0x10c, c );
  416.     }
  417.     return 0;
  418. }
  419.  
  420. smooth4( st, md, fn, x, r )
  421. int st, md, fn, x, r;
  422. {
  423.     int y1, y2, y3;
  424.     int i, n, top, rate, a, b, c;
  425.  
  426.     y1 = ( st + md ) >> 1;
  427.     y2 = md;
  428.     y3 = ( md + fn ) >> 1;
  429.     top = x*2;
  430.     if( y1 == y2 )goto smoo1;
  431.     rate = 128/(y2-y1+1);
  432.     n = 1;
  433.     for( i=y1 ; i<=y2-1 ; i++ ){
  434.         a = EIMpoint_back(x-1,i); // a = WORD( bbuf+top+i*1024-2 );
  435.         b = MYSpoint(x,i); // b = peekw( top+i*1024, 0x10c );
  436.         if( area_chkxy(x,i) /* && (b < 0x8000) */ ){
  437.             c = mix( a, b, n*rate, r );
  438.             EIMpset(x,i,c,DrawNORMAL); // pokew( top+i*1024, 0x10c, c );
  439.         }
  440.         n++;
  441.     }
  442.     if( y2 == y3 )goto smoo2;
  443. smoo1:    if( y2 == y3 )return 0;
  444.     rate = 128/(y3-y2+1);
  445.     n = 1;
  446.     for( i=y2+1 ; i<=y3 ; i++ ){
  447.         a = EIMpoint_back(x+1,i); // a = WORD( bbuf+top+i*1024+2 );
  448.         b = MYSpoint(x,i); // b = peekw( top+i*1024, 0x10c );
  449.         if( area_chkxy(x,i) /* && (b < 0x8000) */ ){
  450.             c = mix( a, b, (128 - n*rate), r );
  451.             EIMpset(x,i,c,DrawNORMAL); // pokew( top+i*1024, 0x10c, c );
  452.         }
  453.         n++;
  454.     }
  455. smoo2:
  456.     a = MYSpoint(x,y2+1); // a = peekw( top+y2*1024+1024, 0x10c );
  457.     b = MYSpoint(x,y2-1); // b = peekw( top+y2*1024-1024, 0x10c );
  458.     if( area_chkxy(x,y2) /*  && (b < 0x8000) */ ){
  459.         c = mix( a, b, 128, r );
  460.         EIMpset(x,y2,c,DrawNORMAL); // pokew( top+y2*1024, 0x10c, c );
  461.     }
  462.     return 0;
  463. }
  464.  
  465. #if 0
  466.  
  467. #endif
  468.  
  469.  
  470.     /* 新しいrand()が合わなくなったんで自家製に切り換え 1993 3/6 */
  471. static int my_rand()
  472. {
  473.     static unsigned int next = 1 ;
  474.  
  475.     next = next * 1103515245 + 12345 ;
  476.     return (unsigned int)( next / 65536 ) % 32768 ;
  477. }
  478.  
  479.  
  480. static int mix( a, b, rate, r )    /* r = random rate ( 0-256 ) ( rate +-r ) */
  481. int a, b, rate, r;
  482. {
  483.     int div, rate1, data, data1, data2, add;
  484.  
  485.     div = 32768/(r*2 + 1);
  486.  
  487.     rate1 = rate + my_rand()/div - r;
  488.     if( rate1 < 0 )rate1 = 0;
  489.     if( rate1 > 256 )rate1 = 256;
  490.     data1 = a & 0x1f; data2 = b & 0x1f;
  491.     add = ( data1*rate1 + data2*(256-rate1) + 0x80 ) >> 8;
  492.     data = add;
  493.  
  494.     rate1 = rate + my_rand()/div - r;
  495.     if( rate1 < 0 )rate1 = 0;
  496.     if( rate1 > 256 )rate1 = 256;
  497.     data1 = (a >> 5) & 0x1f; data2 = (b >> 5) & 0x1f;
  498.     add = ( data1*rate1 + data2*(256-rate1) + 0x80 ) >> 8;
  499.     data = data + ( add << 5 );
  500.  
  501.     rate1 = rate + my_rand()/div - r;
  502.     if( rate1 < 0 )rate1 = 0;
  503.     if( rate1 > 256 )rate1 = 256;
  504.     data1 = (a >> 10) & 0x1f; data2 = (b >> 10) & 0x1f;
  505.     add = ( data1*rate1 + data2*(256-rate1) + 0x80 ) >> 8;
  506.     data = data + ( add << 10 );
  507.     return data;
  508. }
  509.  
  510.  
  511.  
  512.  
  513.  
  514.  
  515. #endif
  516.